package com.zte.claa.inficombo.csa.app.service.modbus.impl;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.zte.claa.inficombo.csa.app.model.redis.DevMeteData;
import com.zte.claa.inficombo.csa.app.service.modbus.ModbusMsgParser;
import com.zte.claa.inficombo.csa.app.service.modbus.ModbusMsgReceiver;
import com.zte.claa.inficombo.csa.app.service.modbus.entity.ModbusMsgWapper;
import com.zte.claa.inficombo.csa.app.service.modbus.entity.ModbusRequestConfig;
import com.zte.claa.inficombo.csa.app.service.modbus.entity.ModbusResponseRelConfig;
import com.zte.claa.inficombo.csa.app.service.resrpt.ResIndexDataRptService;



public class ModbusMsgReceiverImpl implements ModbusMsgReceiver{
	// 日志打印.
	private Logger logger = LoggerFactory.getLogger(ModbusMsgReceiverImpl.class);	
	//modbus响应配置列表
	private Map<String, ModbusResponseRelConfig> modbusResponseRelMap;
	
	//数据发布
	private ResIndexDataRptService dataReport;
	
	//数据解析器
	private Map<String, ModbusMsgParser> msgParserMap;
	
	private LinkedBlockingQueue<ModbusMsgWapper> queue = new LinkedBlockingQueue<>(1000);
	
	private boolean isWorkOn = true;
	
	private ExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
		
	
	public void receive(ModbusMsgWapper msg) throws Exception{
		boolean b =  this.queue.offer(msg);
		if(!b){
			logger.warn("Add modbus msg to queue failed: " + msg.getRequestConfig().getRequestid());
		}
	}
	
	//无参构造
	public ModbusMsgReceiverImpl(){
		
	}
	
	//带消息发布器构造
	public ModbusMsgReceiverImpl(ResIndexDataRptService dataRpt){
		this.dataReport = dataRpt;
	}
	
	//带消息发布器构造与数据解析器的构造
	public ModbusMsgReceiverImpl(ResIndexDataRptService dataRpt, Map<String, ModbusMsgParser> parserMap){
		this.dataReport = dataRpt;
		this.msgParserMap = parserMap;
	}
	
	
	public Map<String,ModbusResponseRelConfig> getModbusResponseRelMap() {
		return modbusResponseRelMap;
	}

	public void setModbusResponseRelMap(Map<String,ModbusResponseRelConfig> modbusResponseRelMap) {
		this.modbusResponseRelMap = modbusResponseRelMap;
	}
	
	@Override
	public void init() throws Exception{
		this.isWorkOn = true;
		
		executorService.submit(new Runnable() {
			@Override
			public void run() {
				processMsg();
			}
		});	
		logger.info("ModbusMsgReceiver process msg thread started");		
	}
	
	
	//处理modbus消息
	private void processMsg(){
		ModbusMsgWapper msg = null;					
		while(this.isWorkOn){			
			try{								
				msg = this.queue.poll(10, TimeUnit.SECONDS);					
				if(msg == null){
					continue;
				} 
				//解析并上报消息
				parserMsgAndReport(msg);
				
			}catch (Throwable t) {
				logger.error("Process msg failed: " + t.getMessage());
			}			
		}
	}
	
	
	//解析消息并发布
	public void parserMsgAndReport(ModbusMsgWapper msg)throws Exception{
		ModbusRequestConfig reqConfig = msg.getRequestConfig();
		if(reqConfig == null){
			return;
		}
		String reqId = reqConfig.getRequestid();		
		ModbusMsgParser msgParser = msgParserMap.get(reqId);
		if(msgParser == null){
			return; 
		}
		
		List<DevMeteData> devMeteDataList = msgParser.parser(msg);	
		if(devMeteDataList != null && devMeteDataList.size() > 0){
			for(DevMeteData devMeteData : devMeteDataList){				
				this.dataReport.submitResIndexData(devMeteData);
			}			
		}			
	}
	
	
	@Override
	public void destory() throws Exception{
		if(executorService != null){
			this.executorService.shutdown();
			this.isWorkOn = false;
			this.executorService = null;
		}
	}
	

}
